/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package org.tnmk.worktime.gui;

import java.awt.event.ItemEvent;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
import javax.swing.JFrame;
import javax.swing.UIManager;
import org.apache.log4j.Logger;
import org.tnmk.common.util.ImageUtils;
import org.tnmk.worktime.config.AppConfig;
import org.tnmk.worktime.gui.utils.WindowUtils;
import org.tnmk.worktime.gui.widget.AboutDialog;
import org.tnmk.worktime.gui.widget.AutoHidePanelPopup;
import org.tnmk.worktime.gui.widget.SystrayIcon;
import org.tnmk.worktime.service.SessionService;
import org.tnmk.worktime.service.action.Action;
import org.tnmk.worktime.service.export.xls.SpendAnalysisExport;
import org.tnmk.worktime.service.model.SessionModel;
import org.tnmk.worktime.utils.TimeUtils;

/**
 *
 * @author tnmkhoi
 */
public class MainFrame extends javax.swing.JFrame {

  static Logger log = Logger.getLogger(MainFrame.class);

  public static final int PERIOD_STATUS = 5;

  private Action leaveAction;
  private Action serviceScheduleAction;
  private SessionService service;
  private final SpendAnalysisExport spendAnalysisExport;
//  private WorkSession editSession;

  protected final DetailController detailController;
  protected final SpendAnalysisController spendAnalysisController;
  protected final HistoryController historyController;
  protected final WaterRemindController waterRemindController;

  /**
   * Creates new form MainFrame
   */
  public MainFrame() {
    setLookAndFeel();
    final MainFrame self = this;
    historyController = new HistoryController(this);
    waterRemindController = new WaterRemindController(this);
    detailController = new DetailController(this);
    spendAnalysisController = new SpendAnalysisController(this);

    //Init controllers
    setType(Type.UTILITY);//must call before initing other components
    initComponents();
    initGUIFrame();
    initGUISystray();

    waterRemindController.initAlertWaterScheduler();

    initWorkTimeService(self);

    detailController.initDetailData(service);
    detailController.initGUI();
    detailController.toDetailGUI();

    spendAnalysisController.initGUI();
    spendAnalysisExport = new SpendAnalysisExport(spendAnalysisController);
    
    historyController.initGUI(service);
    historyController.initHistoryData(service);
    historyController.toHistoryGUI();

    //Stop service when Windows is shutting down
    Runtime.getRuntime().addShutdownHook(
            new Thread(new Runnable() {
              @Override
              public void run() {
                log.info("Shutdown at " + TimeUtils.toString(service.getCurrentTime()));
                getService().stop();
              }
            }));
  }

  private void initGUIFrame() {
    this.setTitle(AppConfig.getTitle());
    WindowUtils.setRight(this);
    setDefaultCloseOperation(JFrame.HIDE_ON_CLOSE); //must call after init default components
  }

  private void initGUISystray() {
    SystrayIcon.initiate(this);
  }

  private void initWorkTimeService(final MainFrame self) {
    service = new SessionService();
    leaveAction = new Action() {
      private boolean showed = false;

      @Override
      public void perform() {
        if (!showed) {
          alertMessage("Time out");
        }
        showed = true;
      }
    };
    service.setOutTimeNotifier(leaveAction);

    serviceScheduleAction = new Action() {
      @Override
      public void perform() {
        SessionModel editingModel = detailController.getViewModel();
        SessionModel currentModel = service.getCurrentSession();
        if (editingModel.getId().equals(currentModel.getId())) {
          detailController.setViewModel(currentModel);
          detailController.toDetailGUI(false, false);
        }
        jlblCurrentTime.setText(AppConfig.toString(service.getCurrentTime()));
      }
    };
    service.setScheduleAction(serviceScheduleAction);
    service.start();
  }

  protected void alertMessage(String message) {
    AutoHidePanelPopup popup = new AutoHidePanelPopup(this, 15);
    popup.setMessage(message);
    popup.show();
  }

  public void setStatus(String status) {
    jlblStatus.setText(status);
    ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1);
    scheduler.schedule(new Runnable() {
      @Override
      public void run() {
        jlblStatus.setText("...");
      }
    }, PERIOD_STATUS, TimeUnit.SECONDS);
  }

  protected void toGUI() {
    this.historyController.toHistoryGUI();
    this.detailController.toDetailGUI();
  }

  /**
   * This method is called from within the constructor to initiate the form. WARNING: Do NOT modify this code. The content of this method is always regenerated by the Form Editor.
   */
  @SuppressWarnings("unchecked")
  // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
  private void initComponents() {

    jScrollPane1 = new javax.swing.JScrollPane();
    jTextArea1 = new javax.swing.JTextArea();
    jLabel6 = new javax.swing.JLabel();
    jgroupHistoryFilter = new javax.swing.ButtonGroup();
    jpanHistory = new javax.swing.JPanel();
    jradWeekFilter = new javax.swing.JRadioButton();
    jradMonthFilter = new javax.swing.JRadioButton();
    jradRangeFilter = new javax.swing.JRadioButton();
    jtxtBeginDateFilter = new javax.swing.JTextField();
    jLabel12 = new javax.swing.JLabel();
    jtxtEndDateFilter = new javax.swing.JTextField();
    jScrollPane3 = new javax.swing.JScrollPane();
    jtblHistory = new javax.swing.JTable();
    jcboWeeks = new javax.swing.JComboBox();
    jcboMonths = new javax.swing.JComboBox();
    jcompDetails = new javax.swing.JTabbedPane();
    jpanWork = new javax.swing.JPanel();
    jtxtInTime = new javax.swing.JTextField();
    jLabel2 = new javax.swing.JLabel();
    jLabel3 = new javax.swing.JLabel();
    jtxtExpectOutTime = new javax.swing.JTextField();
    jLabel13 = new javax.swing.JLabel();
    jtxtOutTime = new javax.swing.JTextField();
    jLabel1 = new javax.swing.JLabel();
    jtxtMustWorkHoursToday = new javax.swing.JTextField();
    jtxtWorkedHours = new javax.swing.JTextField();
    jLabel7 = new javax.swing.JLabel();
    jLabel8 = new javax.swing.JLabel();
    jtxtWeekWorkedHoursHistory = new javax.swing.JTextField();
    jLabel9 = new javax.swing.JLabel();
    jtxtMonthWorkedHours = new javax.swing.JTextField();
    jtxtBreakEndTime = new javax.swing.JTextField();
    jLabel5 = new javax.swing.JLabel();
    jtxtBreakBeginTime = new javax.swing.JTextField();
    jLabel4 = new javax.swing.JLabel();
    jScrollPane2 = new javax.swing.JScrollPane();
    jtxtNote = new javax.swing.JTextArea();
    jcboSessionType = new javax.swing.JComboBox();
    jLabel18 = new javax.swing.JLabel();
    jpanSpend = new javax.swing.JPanel();
    jScrollPane4 = new javax.swing.JScrollPane();
    jtblSpend = new javax.swing.JTable();
    jbtnAddRow = new javax.swing.JButton();
    jLabel14 = new javax.swing.JLabel();
    jtxtSumSpend = new javax.swing.JTextField();
    jLabel15 = new javax.swing.JLabel();
    jtxtSumWeekSpend = new javax.swing.JTextField();
    jLabel16 = new javax.swing.JLabel();
    jtxtSumMonthSpend = new javax.swing.JTextField();
    jpanSpendAnalysis = new javax.swing.JPanel();
    jScrollPane5 = new javax.swing.JScrollPane();
    jtblSpendAnalysis = new javax.swing.JTable();
    jpanSpendSearchInput = new javax.swing.JPanel();
    jtxtSpendSearch = new org.tnmk.worktime.gui.widget.text.JCustomTextField();
    jlblSearch = new javax.swing.JLabel();
    jbtnExportSpendAnalysis = new javax.swing.JButton();
    jpanWater = new javax.swing.JPanel();
    jLabel11 = new javax.swing.JLabel();
    jtxtWater = new javax.swing.JTextField();
    jbtnUpWaterCount = new javax.swing.JButton();
    jLabel10 = new javax.swing.JLabel();
    jtxtWaterAlertPeriod = new javax.swing.JTextField();
    jPanel3 = new javax.swing.JPanel();
    jlblStatus = new javax.swing.JLabel();
    jlblCurrentTime = new javax.swing.JLabel();
    jmenuBar = new javax.swing.JMenuBar();
    jMenu1 = new javax.swing.JMenu();
    jMenuItem3 = new javax.swing.JMenuItem();
    jmenuItemSave = new javax.swing.JMenuItem();
    jMenuItem1 = new javax.swing.JMenuItem();
    jSeparator1 = new javax.swing.JPopupMenu.Separator();
    jMenuItem2 = new javax.swing.JMenuItem();
    jmenuHelp = new javax.swing.JMenu();
    jmenuItemAbout = new javax.swing.JMenuItem();

    jTextArea1.setColumns(20);
    jTextArea1.setRows(5);
    jScrollPane1.setViewportView(jTextArea1);

    jLabel6.setText("jLabel6");

    setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
    setTitle("Daily Record");
    setIconImage(ImageUtils.loadFromClassPath("img/Product.png"));

    jpanHistory.setBorder(javax.swing.BorderFactory.createEtchedBorder());

    jgroupHistoryFilter.add(jradWeekFilter);
    jradWeekFilter.setSelected(true);
    jradWeekFilter.setText("Week");
    jradWeekFilter.addActionListener(new java.awt.event.ActionListener() {
      public void actionPerformed(java.awt.event.ActionEvent evt) {
        jradWeekFilterActionPerformed(evt);
      }
    });

    jgroupHistoryFilter.add(jradMonthFilter);
    jradMonthFilter.setText("Month");
    jradMonthFilter.addActionListener(new java.awt.event.ActionListener() {
      public void actionPerformed(java.awt.event.ActionEvent evt) {
        jradMonthFilterActionPerformed(evt);
      }
    });

    jgroupHistoryFilter.add(jradRangeFilter);
    jradRangeFilter.setText("Date Range");
    jradRangeFilter.addActionListener(new java.awt.event.ActionListener() {
      public void actionPerformed(java.awt.event.ActionEvent evt) {
        jradRangeFilterActionPerformed(evt);
      }
    });

    jtxtBeginDateFilter.setText("01/01/2014 01:00:00 AM");
    jtxtBeginDateFilter.addActionListener(new java.awt.event.ActionListener() {
      public void actionPerformed(java.awt.event.ActionEvent evt) {
        jtxtBeginDateFilterActionPerformed(evt);
      }
    });

    jLabel12.setText(" - ");

    jtxtEndDateFilter.setText("12/12/2014 11:59:59 PM");
    jtxtEndDateFilter.addActionListener(new java.awt.event.ActionListener() {
      public void actionPerformed(java.awt.event.ActionEvent evt) {
        jtxtEndDateFilterActionPerformed(evt);
      }
    });

    jtblHistory.setModel(new javax.swing.table.DefaultTableModel(
      new Object [][] {

      },
      new String [] {
        "In Time", "Out Time", "Worked Hours", " "
      }
    ));
    jtblHistory.setSelectionBackground(new java.awt.Color(227, 227, 227));
    jtblHistory.setSelectionForeground(new java.awt.Color(0, 0, 0));
    jScrollPane3.setViewportView(jtblHistory);

    jcboWeeks.addActionListener(new java.awt.event.ActionListener() {
      public void actionPerformed(java.awt.event.ActionEvent evt) {
        jcboWeeksActionPerformed(evt);
      }
    });

    jcboMonths.addActionListener(new java.awt.event.ActionListener() {
      public void actionPerformed(java.awt.event.ActionEvent evt) {
        jcboMonthsActionPerformed(evt);
      }
    });

    javax.swing.GroupLayout jpanHistoryLayout = new javax.swing.GroupLayout(jpanHistory);
    jpanHistory.setLayout(jpanHistoryLayout);
    jpanHistoryLayout.setHorizontalGroup(
      jpanHistoryLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
      .addComponent(jScrollPane3)
      .addGroup(jpanHistoryLayout.createSequentialGroup()
        .addContainerGap()
        .addGroup(jpanHistoryLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
          .addGroup(jpanHistoryLayout.createSequentialGroup()
            .addComponent(jradWeekFilter)
            .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
            .addComponent(jcboWeeks, 0, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
          .addGroup(jpanHistoryLayout.createSequentialGroup()
            .addComponent(jradRangeFilter)
            .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
            .addComponent(jtxtBeginDateFilter)))
        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
        .addComponent(jLabel12)
        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
        .addGroup(jpanHistoryLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
          .addGroup(jpanHistoryLayout.createSequentialGroup()
            .addComponent(jradMonthFilter)
            .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
            .addComponent(jcboMonths, 0, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
          .addComponent(jtxtEndDateFilter, javax.swing.GroupLayout.PREFERRED_SIZE, 278, javax.swing.GroupLayout.PREFERRED_SIZE))
        .addContainerGap())
    );
    jpanHistoryLayout.setVerticalGroup(
      jpanHistoryLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
      .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jpanHistoryLayout.createSequentialGroup()
        .addComponent(jScrollPane3, javax.swing.GroupLayout.PREFERRED_SIZE, 167, javax.swing.GroupLayout.PREFERRED_SIZE)
        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
        .addGroup(jpanHistoryLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
          .addComponent(jradWeekFilter)
          .addComponent(jradMonthFilter)
          .addComponent(jcboWeeks, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
          .addComponent(jcboMonths, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
        .addGroup(jpanHistoryLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
          .addComponent(jradRangeFilter)
          .addComponent(jtxtBeginDateFilter, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
          .addComponent(jLabel12)
          .addComponent(jtxtEndDateFilter, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
        .addContainerGap())
    );

    jtxtInTime.setFont(new java.awt.Font("Tahoma", 1, 11)); // NOI18N
    jtxtInTime.setText("25/06/2014 08:23:47 AM");
    jtxtInTime.addActionListener(new java.awt.event.ActionListener() {
      public void actionPerformed(java.awt.event.ActionEvent evt) {
        jtxtInTimeActionPerformed(evt);
      }
    });

    jLabel2.setText("In Time");

    jLabel3.setText("Expect Out Time");

    jtxtExpectOutTime.setEditable(false);
    jtxtExpectOutTime.setFont(new java.awt.Font("Tahoma", 1, 11)); // NOI18N
    jtxtExpectOutTime.setText("jTextField1");

    jLabel13.setText("Actual Out Time");

    jtxtOutTime.setFont(new java.awt.Font("Tahoma", 1, 11)); // NOI18N
    jtxtOutTime.setText("jTextField1");
    jtxtOutTime.addActionListener(new java.awt.event.ActionListener() {
      public void actionPerformed(java.awt.event.ActionEvent evt) {
        jtxtOutTimeActionPerformed(evt);
      }
    });

    jLabel1.setText("Must Work Hours in Day");

    jtxtMustWorkHoursToday.setEditable(false);
    jtxtMustWorkHoursToday.setFont(new java.awt.Font("Tahoma", 1, 11)); // NOI18N
    jtxtMustWorkHoursToday.setText("8");
    jtxtMustWorkHoursToday.addActionListener(new java.awt.event.ActionListener() {
      public void actionPerformed(java.awt.event.ActionEvent evt) {
        jtxtMustWorkHoursTodayActionPerformed(evt);
      }
    });

    jtxtWorkedHours.setEditable(false);
    jtxtWorkedHours.setFont(new java.awt.Font("Tahoma", 1, 11)); // NOI18N
    jtxtWorkedHours.setText("7.56");

    jLabel7.setText("Actual Worked Hours in Day");

    jLabel8.setText("Worked Hours in Week");

    jtxtWeekWorkedHoursHistory.setEditable(false);
    jtxtWeekWorkedHoursHistory.setText("jTextField1");

    jLabel9.setText("Worked Hours in Month");

    jtxtMonthWorkedHours.setEditable(false);
    jtxtMonthWorkedHours.setText("jTextField1");

    jtxtBreakEndTime.setEditable(false);
    jtxtBreakEndTime.setText("25/06/2014 08:23:47 AM");

    jLabel5.setHorizontalAlignment(javax.swing.SwingConstants.CENTER);
    jLabel5.setText(" - ");

    jtxtBreakBeginTime.setEditable(false);
    jtxtBreakBeginTime.setText("jTextField1");

    jLabel4.setText("Break Time");

    jtxtNote.setColumns(20);
    jtxtNote.setFont(new java.awt.Font("Arial", 0, 11)); // NOI18N
    jtxtNote.setLineWrap(true);
    jtxtNote.setRows(5);
    jtxtNote.setWrapStyleWord(true);
    jtxtNote.addKeyListener(new java.awt.event.KeyAdapter() {
      public void keyPressed(java.awt.event.KeyEvent evt) {
        jtxtNoteKeyPressed(evt);
      }
    });
    jScrollPane2.setViewportView(jtxtNote);

    jcboSessionType.addItemListener(new java.awt.event.ItemListener() {
      public void itemStateChanged(java.awt.event.ItemEvent evt) {
        jcboSessionTypeItemStateChanged(evt);
      }
    });
    jcboSessionType.addActionListener(new java.awt.event.ActionListener() {
      public void actionPerformed(java.awt.event.ActionEvent evt) {
        jcboSessionTypeActionPerformed(evt);
      }
    });

    jLabel18.setText("Session Type");

    javax.swing.GroupLayout jpanWorkLayout = new javax.swing.GroupLayout(jpanWork);
    jpanWork.setLayout(jpanWorkLayout);
    jpanWorkLayout.setHorizontalGroup(
      jpanWorkLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
      .addGroup(jpanWorkLayout.createSequentialGroup()
        .addContainerGap()
        .addGroup(jpanWorkLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
          .addComponent(jScrollPane2)
          .addGroup(jpanWorkLayout.createSequentialGroup()
            .addGroup(jpanWorkLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
              .addGroup(jpanWorkLayout.createSequentialGroup()
                .addComponent(jLabel3)
                .addGap(40, 40, 40))
              .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jpanWorkLayout.createSequentialGroup()
                .addComponent(jLabel2, javax.swing.GroupLayout.PREFERRED_SIZE, 115, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)))
            .addGroup(jpanWorkLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
              .addComponent(jtxtExpectOutTime)
              .addComponent(jtxtInTime, javax.swing.GroupLayout.PREFERRED_SIZE, 158, javax.swing.GroupLayout.PREFERRED_SIZE))
            .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
            .addGroup(jpanWorkLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
              .addComponent(jLabel1)
              .addComponent(jLabel18))
            .addGap(29, 29, 29)
            .addGroup(jpanWorkLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
              .addComponent(jcboSessionType, 0, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
              .addComponent(jtxtMustWorkHoursToday)))
          .addGroup(jpanWorkLayout.createSequentialGroup()
            .addComponent(jLabel13)
            .addGap(43, 43, 43)
            .addComponent(jtxtOutTime, javax.swing.GroupLayout.PREFERRED_SIZE, 158, javax.swing.GroupLayout.PREFERRED_SIZE)
            .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
            .addComponent(jLabel7, javax.swing.GroupLayout.PREFERRED_SIZE, 140, javax.swing.GroupLayout.PREFERRED_SIZE)
            .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
            .addComponent(jtxtWorkedHours))
          .addGroup(jpanWorkLayout.createSequentialGroup()
            .addGroup(jpanWorkLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
              .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jpanWorkLayout.createSequentialGroup()
                .addComponent(jLabel4)
                .addGap(67, 67, 67)
                .addComponent(jtxtBreakBeginTime, javax.swing.GroupLayout.PREFERRED_SIZE, 158, javax.swing.GroupLayout.PREFERRED_SIZE))
              .addGroup(jpanWorkLayout.createSequentialGroup()
                .addComponent(jLabel8)
                .addGap(10, 10, 10)
                .addComponent(jtxtWeekWorkedHoursHistory, javax.swing.GroupLayout.PREFERRED_SIZE, 158, javax.swing.GroupLayout.PREFERRED_SIZE)))
            .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
            .addGroup(jpanWorkLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
              .addGroup(jpanWorkLayout.createSequentialGroup()
                .addComponent(jLabel5, javax.swing.GroupLayout.PREFERRED_SIZE, 110, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addGap(34, 34, 34)
                .addComponent(jtxtBreakEndTime, javax.swing.GroupLayout.DEFAULT_SIZE, 160, Short.MAX_VALUE))
              .addGroup(jpanWorkLayout.createSequentialGroup()
                .addComponent(jLabel9, javax.swing.GroupLayout.PREFERRED_SIZE, 134, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                .addComponent(jtxtMonthWorkedHours)))))
        .addContainerGap())
    );
    jpanWorkLayout.setVerticalGroup(
      jpanWorkLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
      .addGroup(jpanWorkLayout.createSequentialGroup()
        .addContainerGap()
        .addGroup(jpanWorkLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
          .addComponent(jtxtInTime, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
          .addComponent(jLabel2)
          .addComponent(jcboSessionType, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
          .addComponent(jLabel18))
        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
        .addGroup(jpanWorkLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
          .addComponent(jtxtExpectOutTime, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
          .addComponent(jLabel3)
          .addComponent(jLabel1)
          .addComponent(jtxtMustWorkHoursToday, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
        .addGroup(jpanWorkLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
          .addComponent(jtxtOutTime, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
          .addComponent(jLabel13)
          .addComponent(jLabel7)
          .addComponent(jtxtWorkedHours, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
        .addGroup(jpanWorkLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
          .addComponent(jLabel8)
          .addComponent(jtxtWeekWorkedHoursHistory, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
          .addComponent(jLabel9)
          .addComponent(jtxtMonthWorkedHours, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
        .addGroup(jpanWorkLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
          .addComponent(jLabel4)
          .addComponent(jtxtBreakBeginTime, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
          .addComponent(jLabel5)
          .addComponent(jtxtBreakEndTime, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
        .addComponent(jScrollPane2, javax.swing.GroupLayout.DEFAULT_SIZE, 213, Short.MAX_VALUE)
        .addContainerGap())
    );

    jcompDetails.addTab("Work", jpanWork);

    jtblSpend.setModel(new javax.swing.table.DefaultTableModel(
      new Object [][] {

      },
      new String [] {
        "Money", "Note", ""
      }
    ) {
      Class[] types = new Class [] {
        java.lang.Long.class, java.lang.Object.class, java.lang.Object.class
      };

      public Class getColumnClass(int columnIndex) {
        return types [columnIndex];
      }
    });
    jtblSpend.setGridColor(java.awt.SystemColor.control);
    jtblSpend.setRowSelectionAllowed(false);
    jScrollPane4.setViewportView(jtblSpend);

    jbtnAddRow.setIcon(new javax.swing.ImageIcon(getClass().getResource("/img/form/plus.png"))); // NOI18N
    jbtnAddRow.setText("Add row");
    jbtnAddRow.setHorizontalAlignment(javax.swing.SwingConstants.LEFT);
    jbtnAddRow.setHorizontalTextPosition(javax.swing.SwingConstants.RIGHT);
    jbtnAddRow.addActionListener(new java.awt.event.ActionListener() {
      public void actionPerformed(java.awt.event.ActionEvent evt) {
        jbtnAddRowActionPerformed(evt);
      }
    });

    jLabel14.setText("Session Spend");

    jtxtSumSpend.setEditable(false);
    jtxtSumSpend.setFont(new java.awt.Font("Tahoma", 1, 11)); // NOI18N
    jtxtSumSpend.setText("0");

    jLabel15.setText("Week Spend");

    jtxtSumWeekSpend.setEditable(false);
    jtxtSumWeekSpend.setText("0");

    jLabel16.setText("Month Spend");

    jtxtSumMonthSpend.setEditable(false);
    jtxtSumMonthSpend.setText("0");

    javax.swing.GroupLayout jpanSpendLayout = new javax.swing.GroupLayout(jpanSpend);
    jpanSpend.setLayout(jpanSpendLayout);
    jpanSpendLayout.setHorizontalGroup(
      jpanSpendLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
      .addGroup(jpanSpendLayout.createSequentialGroup()
        .addContainerGap()
        .addGroup(jpanSpendLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
          .addComponent(jScrollPane4, javax.swing.GroupLayout.DEFAULT_SIZE, 585, Short.MAX_VALUE)
          .addGroup(jpanSpendLayout.createSequentialGroup()
            .addComponent(jbtnAddRow, javax.swing.GroupLayout.PREFERRED_SIZE, 95, javax.swing.GroupLayout.PREFERRED_SIZE)
            .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
            .addComponent(jLabel14)
            .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
            .addComponent(jtxtSumSpend, javax.swing.GroupLayout.PREFERRED_SIZE, 103, javax.swing.GroupLayout.PREFERRED_SIZE)
            .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
            .addComponent(jLabel15)
            .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
            .addComponent(jtxtSumWeekSpend, javax.swing.GroupLayout.PREFERRED_SIZE, 81, javax.swing.GroupLayout.PREFERRED_SIZE)
            .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
            .addComponent(jLabel16)
            .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
            .addComponent(jtxtSumMonthSpend)))
        .addContainerGap())
    );
    jpanSpendLayout.setVerticalGroup(
      jpanSpendLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
      .addGroup(jpanSpendLayout.createSequentialGroup()
        .addContainerGap()
        .addComponent(jScrollPane4, javax.swing.GroupLayout.PREFERRED_SIZE, 322, javax.swing.GroupLayout.PREFERRED_SIZE)
        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
        .addGroup(jpanSpendLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
          .addComponent(jbtnAddRow)
          .addComponent(jLabel14)
          .addComponent(jtxtSumSpend, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
          .addComponent(jLabel15)
          .addComponent(jtxtSumWeekSpend, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
          .addComponent(jtxtSumMonthSpend, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
          .addComponent(jLabel16))
        .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
    );

    jcompDetails.addTab("Spend", jpanSpend);

    jtblSpendAnalysis.setModel(new javax.swing.table.DefaultTableModel(
      new Object [][] {

      },
      new String [] {
        "Date", "Spend Note", "Cost", "Id"
      }
    ) {
      Class[] types = new Class [] {
        java.lang.Object.class, java.lang.Object.class, java.lang.Long.class, java.lang.Integer.class
      };

      public Class getColumnClass(int columnIndex) {
        return types [columnIndex];
      }
    });
    jtblSpendAnalysis.setGridColor(java.awt.SystemColor.control);
    jtblSpendAnalysis.setRowSelectionAllowed(false);
    jtblSpendAnalysis.setSelectionMode(javax.swing.ListSelectionModel.SINGLE_SELECTION);
    jScrollPane5.setViewportView(jtblSpendAnalysis);
    if (jtblSpendAnalysis.getColumnModel().getColumnCount() > 0) {
      jtblSpendAnalysis.getColumnModel().getColumn(0).setMinWidth(75);
      jtblSpendAnalysis.getColumnModel().getColumn(0).setPreferredWidth(75);
      jtblSpendAnalysis.getColumnModel().getColumn(0).setMaxWidth(75);
      jtblSpendAnalysis.getColumnModel().getColumn(2).setMinWidth(75);
      jtblSpendAnalysis.getColumnModel().getColumn(2).setPreferredWidth(75);
      jtblSpendAnalysis.getColumnModel().getColumn(2).setMaxWidth(75);
      jtblSpendAnalysis.getColumnModel().getColumn(3).setMinWidth(30);
      jtblSpendAnalysis.getColumnModel().getColumn(3).setPreferredWidth(30);
      jtblSpendAnalysis.getColumnModel().getColumn(3).setMaxWidth(30);
    }

    jpanSpendSearchInput.setBackground(javax.swing.UIManager.getDefaults().getColor("FormattedTextField.background"));
    jpanSpendSearchInput.setBorder(javax.swing.BorderFactory.createLineBorder(new java.awt.Color(153, 153, 153)));

    jtxtSpendSearch.setBorder(null);
    jtxtSpendSearch.setPlaceHolder("Spend Search");
    jtxtSpendSearch.addActionListener(new java.awt.event.ActionListener() {
      public void actionPerformed(java.awt.event.ActionEvent evt) {
        jtxtSpendSearchActionPerformed(evt);
      }
    });

    jlblSearch.setBackground(new java.awt.Color(245, 243, 242));
    jlblSearch.setHorizontalAlignment(javax.swing.SwingConstants.CENTER);
    jlblSearch.setIcon(new javax.swing.ImageIcon(getClass().getResource("/img/form/search_16.png"))); // NOI18N
    jlblSearch.setBorder(javax.swing.BorderFactory.createCompoundBorder(javax.swing.BorderFactory.createMatteBorder(0, 1, 0, 0, new java.awt.Color(204, 204, 204)), javax.swing.BorderFactory.createMatteBorder(0, 1, 0, 0, new java.awt.Color(255, 255, 255))));
    jlblSearch.setOpaque(true);
    jlblSearch.addMouseListener(new java.awt.event.MouseAdapter() {
      public void mouseClicked(java.awt.event.MouseEvent evt) {
        jlblSearchMouseClicked(evt);
      }
    });

    javax.swing.GroupLayout jpanSpendSearchInputLayout = new javax.swing.GroupLayout(jpanSpendSearchInput);
    jpanSpendSearchInput.setLayout(jpanSpendSearchInputLayout);
    jpanSpendSearchInputLayout.setHorizontalGroup(
      jpanSpendSearchInputLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
      .addGroup(jpanSpendSearchInputLayout.createSequentialGroup()
        .addGap(4, 4, 4)
        .addComponent(jtxtSpendSearch, javax.swing.GroupLayout.DEFAULT_SIZE, 208, Short.MAX_VALUE)
        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
        .addComponent(jlblSearch, javax.swing.GroupLayout.PREFERRED_SIZE, 24, javax.swing.GroupLayout.PREFERRED_SIZE))
    );
    jpanSpendSearchInputLayout.setVerticalGroup(
      jpanSpendSearchInputLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
      .addComponent(jlblSearch, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
      .addComponent(jtxtSpendSearch, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
    );

    jbtnExportSpendAnalysis.setText("Export");
    jbtnExportSpendAnalysis.addActionListener(new java.awt.event.ActionListener() {
      public void actionPerformed(java.awt.event.ActionEvent evt) {
        jbtnExportSpendAnalysisActionPerformed(evt);
      }
    });

    javax.swing.GroupLayout jpanSpendAnalysisLayout = new javax.swing.GroupLayout(jpanSpendAnalysis);
    jpanSpendAnalysis.setLayout(jpanSpendAnalysisLayout);
    jpanSpendAnalysisLayout.setHorizontalGroup(
      jpanSpendAnalysisLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
      .addGroup(jpanSpendAnalysisLayout.createSequentialGroup()
        .addContainerGap()
        .addGroup(jpanSpendAnalysisLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
          .addComponent(jScrollPane5, javax.swing.GroupLayout.DEFAULT_SIZE, 585, Short.MAX_VALUE)
          .addGroup(jpanSpendAnalysisLayout.createSequentialGroup()
            .addComponent(jpanSpendSearchInput, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
            .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
            .addComponent(jbtnExportSpendAnalysis)
            .addGap(0, 0, Short.MAX_VALUE)))
        .addContainerGap())
    );
    jpanSpendAnalysisLayout.setVerticalGroup(
      jpanSpendAnalysisLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
      .addGroup(jpanSpendAnalysisLayout.createSequentialGroup()
        .addGap(10, 10, 10)
        .addGroup(jpanSpendAnalysisLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
          .addComponent(jpanSpendSearchInput, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
          .addGroup(jpanSpendAnalysisLayout.createSequentialGroup()
            .addComponent(jbtnExportSpendAnalysis)
            .addGap(0, 0, Short.MAX_VALUE)))
        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
        .addComponent(jScrollPane5, javax.swing.GroupLayout.PREFERRED_SIZE, 319, javax.swing.GroupLayout.PREFERRED_SIZE)
        .addContainerGap())
    );

    jcompDetails.addTab("Spend Anlysis", jpanSpendAnalysis);

    jLabel11.setText("Water finished");

    jtxtWater.setText("0");
    jtxtWater.addActionListener(new java.awt.event.ActionListener() {
      public void actionPerformed(java.awt.event.ActionEvent evt) {
        jtxtWaterActionPerformed(evt);
      }
    });

    jbtnUpWaterCount.setText("^");
    jbtnUpWaterCount.addActionListener(new java.awt.event.ActionListener() {
      public void actionPerformed(java.awt.event.ActionEvent evt) {
        jbtnUpWaterCountActionPerformed(evt);
      }
    });

    jLabel10.setText("Water Alert");

    jtxtWaterAlertPeriod.setText("3600");
    jtxtWaterAlertPeriod.addActionListener(new java.awt.event.ActionListener() {
      public void actionPerformed(java.awt.event.ActionEvent evt) {
        jtxtWaterAlertPeriodActionPerformed(evt);
      }
    });

    javax.swing.GroupLayout jpanWaterLayout = new javax.swing.GroupLayout(jpanWater);
    jpanWater.setLayout(jpanWaterLayout);
    jpanWaterLayout.setHorizontalGroup(
      jpanWaterLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
      .addGroup(jpanWaterLayout.createSequentialGroup()
        .addContainerGap()
        .addComponent(jLabel11)
        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
        .addComponent(jtxtWater, javax.swing.GroupLayout.PREFERRED_SIZE, 56, javax.swing.GroupLayout.PREFERRED_SIZE)
        .addGap(10, 10, 10)
        .addComponent(jbtnUpWaterCount)
        .addGap(26, 26, 26)
        .addComponent(jLabel10)
        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
        .addComponent(jtxtWaterAlertPeriod, javax.swing.GroupLayout.PREFERRED_SIZE, 156, javax.swing.GroupLayout.PREFERRED_SIZE)
        .addContainerGap(170, Short.MAX_VALUE))
    );
    jpanWaterLayout.setVerticalGroup(
      jpanWaterLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
      .addGroup(jpanWaterLayout.createSequentialGroup()
        .addContainerGap()
        .addGroup(jpanWaterLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
          .addGroup(jpanWaterLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
            .addComponent(jtxtWater, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
            .addComponent(jLabel11)
            .addComponent(jbtnUpWaterCount))
          .addGroup(jpanWaterLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
            .addComponent(jLabel10)
            .addComponent(jtxtWaterAlertPeriod, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)))
        .addContainerGap(338, Short.MAX_VALUE))
    );

    jcompDetails.addTab("Water", jpanWater);

    jPanel3.setBackground(new java.awt.Color(102, 102, 102));
    jPanel3.setBorder(javax.swing.BorderFactory.createCompoundBorder(javax.swing.BorderFactory.createMatteBorder(1, 0, 0, 0, new java.awt.Color(0, 0, 0)), javax.swing.BorderFactory.createMatteBorder(2, 0, 0, 0, new java.awt.Color(90, 90, 90))));
    jPanel3.setForeground(new java.awt.Color(255, 255, 255));

    jlblStatus.setForeground(new java.awt.Color(255, 255, 255));
    jlblStatus.setHorizontalAlignment(javax.swing.SwingConstants.CENTER);
    jlblStatus.setText("...");

    jlblCurrentTime.setFont(new java.awt.Font("Tahoma", 1, 11)); // NOI18N
    jlblCurrentTime.setForeground(new java.awt.Color(255, 255, 255));
    jlblCurrentTime.setHorizontalAlignment(javax.swing.SwingConstants.RIGHT);
    jlblCurrentTime.setText("current time");

    javax.swing.GroupLayout jPanel3Layout = new javax.swing.GroupLayout(jPanel3);
    jPanel3.setLayout(jPanel3Layout);
    jPanel3Layout.setHorizontalGroup(
      jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
      .addGroup(jPanel3Layout.createSequentialGroup()
        .addContainerGap()
        .addComponent(jlblStatus, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
        .addComponent(jlblCurrentTime, javax.swing.GroupLayout.PREFERRED_SIZE, 196, javax.swing.GroupLayout.PREFERRED_SIZE)
        .addContainerGap())
    );
    jPanel3Layout.setVerticalGroup(
      jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
      .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanel3Layout.createSequentialGroup()
        .addGap(0, 0, Short.MAX_VALUE)
        .addGroup(jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
          .addComponent(jlblStatus, javax.swing.GroupLayout.PREFERRED_SIZE, 31, javax.swing.GroupLayout.PREFERRED_SIZE)
          .addComponent(jlblCurrentTime, javax.swing.GroupLayout.PREFERRED_SIZE, 31, javax.swing.GroupLayout.PREFERRED_SIZE)))
    );

    jMenu1.setText("File");

    jMenuItem3.setText("Export");
    jMenuItem3.addActionListener(new java.awt.event.ActionListener() {
      public void actionPerformed(java.awt.event.ActionEvent evt) {
        jMenuItem3ActionPerformed(evt);
      }
    });
    jMenu1.add(jMenuItem3);

    jmenuItemSave.setAccelerator(javax.swing.KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_S, java.awt.event.InputEvent.CTRL_MASK));
    jmenuItemSave.setText("Save");
    jmenuItemSave.addActionListener(new java.awt.event.ActionListener() {
      public void actionPerformed(java.awt.event.ActionEvent evt) {
        jmenuItemSaveActionPerformed(evt);
      }
    });
    jMenu1.add(jmenuItemSave);

    jMenuItem1.setAccelerator(javax.swing.KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_S, java.awt.event.InputEvent.SHIFT_MASK | java.awt.event.InputEvent.CTRL_MASK));
    jMenuItem1.setText("Backup");
    jMenuItem1.addActionListener(new java.awt.event.ActionListener() {
      public void actionPerformed(java.awt.event.ActionEvent evt) {
        jMenuItem1ActionPerformed(evt);
      }
    });
    jMenu1.add(jMenuItem1);
    jMenu1.add(jSeparator1);

    jMenuItem2.setAccelerator(javax.swing.KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_E, java.awt.event.InputEvent.ALT_MASK | java.awt.event.InputEvent.CTRL_MASK));
    jMenuItem2.setText("Exit");
    jMenuItem2.addActionListener(new java.awt.event.ActionListener() {
      public void actionPerformed(java.awt.event.ActionEvent evt) {
        jMenuItem2ActionPerformed(evt);
      }
    });
    jMenu1.add(jMenuItem2);

    jmenuBar.add(jMenu1);

    jmenuHelp.setText("Help");
    jmenuHelp.addActionListener(new java.awt.event.ActionListener() {
      public void actionPerformed(java.awt.event.ActionEvent evt) {
        jmenuHelpActionPerformed(evt);
      }
    });

    jmenuItemAbout.setAccelerator(javax.swing.KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_F1, 0));
    jmenuItemAbout.setText("About");
    jmenuItemAbout.addActionListener(new java.awt.event.ActionListener() {
      public void actionPerformed(java.awt.event.ActionEvent evt) {
        jmenuItemAboutActionPerformed(evt);
      }
    });
    jmenuHelp.add(jmenuItemAbout);

    jmenuBar.add(jmenuHelp);

    setJMenuBar(jmenuBar);

    javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
    getContentPane().setLayout(layout);
    layout.setHorizontalGroup(
      layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
      .addGroup(layout.createSequentialGroup()
        .addContainerGap()
        .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
          .addComponent(jcompDetails)
          .addComponent(jpanHistory, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
        .addContainerGap())
      .addComponent(jPanel3, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
    );
    layout.setVerticalGroup(
      layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
      .addGroup(layout.createSequentialGroup()
        .addContainerGap()
        .addComponent(jcompDetails, javax.swing.GroupLayout.PREFERRED_SIZE, 397, javax.swing.GroupLayout.PREFERRED_SIZE)
        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
        .addComponent(jpanHistory, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
        .addComponent(jPanel3, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
        .addGap(0, 0, 0))
    );

    pack();
  }// </editor-fold>//GEN-END:initComponents

  private void jtxtInTimeActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jtxtInTimeActionPerformed
    // TODO add your handling code here:
    detailController.updateInTime();
  }//GEN-LAST:event_jtxtInTimeActionPerformed

  private void jtxtMustWorkHoursTodayActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jtxtMustWorkHoursTodayActionPerformed
    // TODO add your handling code here:
  }//GEN-LAST:event_jtxtMustWorkHoursTodayActionPerformed

  private void jtxtWaterAlertPeriodActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jtxtWaterAlertPeriodActionPerformed
    // TODO add your handling code here:
    waterRemindController.updateWaterAlertPeriod();
  }//GEN-LAST:event_jtxtWaterAlertPeriodActionPerformed

  private void jtxtNoteKeyPressed(java.awt.event.KeyEvent evt) {//GEN-FIRST:event_jtxtNoteKeyPressed
    String note = jtxtNote.getText();
    detailController.getViewModel().setNote(note);
  }//GEN-LAST:event_jtxtNoteKeyPressed

  private void jtxtWaterActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jtxtWaterActionPerformed
    waterRemindController.updateWaterCount();
  }//GEN-LAST:event_jtxtWaterActionPerformed

  private void jbtnUpWaterCountActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jbtnUpWaterCountActionPerformed
    waterRemindController.increaseWaterCount();
  }//GEN-LAST:event_jbtnUpWaterCountActionPerformed

  private void jmenuItemSaveActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jmenuItemSaveActionPerformed
    service.saveAll();
    setStatus("Saved");
  }//GEN-LAST:event_jmenuItemSaveActionPerformed

  private void jMenuItem1ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jMenuItem1ActionPerformed
    service.backupData();
    setStatus("Backuped");
  }//GEN-LAST:event_jMenuItem1ActionPerformed

  private void jMenuItem2ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jMenuItem2ActionPerformed
    exit();
  }//GEN-LAST:event_jMenuItem2ActionPerformed

  private void jradWeekFilterActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jradWeekFilterActionPerformed
    historyController.selectGUIWeekFilter();
  }//GEN-LAST:event_jradWeekFilterActionPerformed

  private void jradRangeFilterActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jradRangeFilterActionPerformed
    historyController.selectGUIRangeFilter();
  }//GEN-LAST:event_jradRangeFilterActionPerformed

  private void jradMonthFilterActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jradMonthFilterActionPerformed
    historyController.selectGUIMonthFilter();
  }//GEN-LAST:event_jradMonthFilterActionPerformed

  private void jtxtBeginDateFilterActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jtxtBeginDateFilterActionPerformed
    jradRangeFilter.setSelected(true);
    historyController.selectGUIRangeFilter();
  }//GEN-LAST:event_jtxtBeginDateFilterActionPerformed

  private void jtxtEndDateFilterActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jtxtEndDateFilterActionPerformed
    jradRangeFilter.setSelected(true);
    historyController.selectGUIRangeFilter();
  }//GEN-LAST:event_jtxtEndDateFilterActionPerformed

  private void jtxtOutTimeActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jtxtOutTimeActionPerformed
    detailController.updateOutTime();
  }//GEN-LAST:event_jtxtOutTimeActionPerformed

  private void jbtnAddRowActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jbtnAddRowActionPerformed
    detailController.addSpendEntry();
  }//GEN-LAST:event_jbtnAddRowActionPerformed

  private void jtxtSpendSearchActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jtxtSpendSearchActionPerformed
    spendAnalysisController.filterSpendInCurrentFilteredSessions();
  }//GEN-LAST:event_jtxtSpendSearchActionPerformed

  private void jcboWeeksActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jcboWeeksActionPerformed
    jradWeekFilter.setSelected(true);
    historyController.selectGUIWeekFilter();
  }//GEN-LAST:event_jcboWeeksActionPerformed

  private void jcboMonthsActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jcboMonthsActionPerformed
    jradMonthFilter.setSelected(true);
    historyController.selectGUIMonthFilter();
  }//GEN-LAST:event_jcboMonthsActionPerformed

  private void jmenuHelpActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jmenuHelpActionPerformed
    // TODO add your handling code here:
  }//GEN-LAST:event_jmenuHelpActionPerformed

  private void jmenuItemAboutActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jmenuItemAboutActionPerformed
    // TODO add your handling code here:
    AboutDialog aboutDialog = new AboutDialog(this);
    aboutDialog.show();
  }//GEN-LAST:event_jmenuItemAboutActionPerformed

  private void jlblSearchMouseClicked(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_jlblSearchMouseClicked
    // TODO add your handling code here:
    spendAnalysisController.filterSpendInCurrentFilteredSessions();
  }//GEN-LAST:event_jlblSearchMouseClicked

  private void jcboSessionTypeActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jcboSessionTypeActionPerformed
    // TODO add your handling code here:

  }//GEN-LAST:event_jcboSessionTypeActionPerformed

  private void jcboSessionTypeItemStateChanged(java.awt.event.ItemEvent evt) {//GEN-FIRST:event_jcboSessionTypeItemStateChanged
    if (evt.getStateChange() == ItemEvent.SELECTED) {
      detailController.updateSessionType();
    }
  }//GEN-LAST:event_jcboSessionTypeItemStateChanged

  private void jMenuItem3ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jMenuItem3ActionPerformed
    // TODO add your handling code here:

  }//GEN-LAST:event_jMenuItem3ActionPerformed

  private void jbtnExportSpendAnalysisActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jbtnExportSpendAnalysisActionPerformed
    // TODO add your handling code here:
    spendAnalysisExport.export();
  }//GEN-LAST:event_jbtnExportSpendAnalysisActionPerformed

  public void exit() {
    SystrayIcon.remove();
    System.exit(0);
  }

  /**
   * @param args the command line arguments
   */
  public static void main(String args[]) {
    /* Set the Nimbus look and feel */
    //<editor-fold defaultstate="collapsed" desc=" Look and feel setting code (optional) ">
        /* If Nimbus (introduced in Java SE 6) is not available, stay with the default look and feel.
     * For details see http://download.oracle.com/javase/tutorial/uiswing/lookandfeel/plaf.html 
     */
    try {
      for (javax.swing.UIManager.LookAndFeelInfo info : javax.swing.UIManager.getInstalledLookAndFeels()) {
        if ("Nimbus".equals(info.getName())) {
          javax.swing.UIManager.setLookAndFeel(info.getClassName());
          break;
        }
      }
    } catch (ClassNotFoundException ex) {
      java.util.logging.Logger.getLogger(MainFrame.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
    } catch (InstantiationException ex) {
      java.util.logging.Logger.getLogger(MainFrame.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
    } catch (IllegalAccessException ex) {
      java.util.logging.Logger.getLogger(MainFrame.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
    } catch (javax.swing.UnsupportedLookAndFeelException ex) {
      java.util.logging.Logger.getLogger(MainFrame.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
    }
    //</editor-fold>

    /* Create and display the form */
    java.awt.EventQueue.invokeLater(new Runnable() {
      public void run() {
        MainFrame mf = new MainFrame();
        mf.setVisible(true);
      }
    });
  }

  private static void setLookAndFeel() {
    try {
      UIManager.setLookAndFeel("com.sun.java.swing.plaf.windows.WindowsLookAndFeel");
    } catch (Exception e) {
      log.error("Cannot set Look & Feel", e);
    }
  }
  // Variables declaration - do not modify//GEN-BEGIN:variables
  private javax.swing.JLabel jLabel1;
  private javax.swing.JLabel jLabel10;
  private javax.swing.JLabel jLabel11;
  private javax.swing.JLabel jLabel12;
  private javax.swing.JLabel jLabel13;
  private javax.swing.JLabel jLabel14;
  private javax.swing.JLabel jLabel15;
  private javax.swing.JLabel jLabel16;
  private javax.swing.JLabel jLabel18;
  private javax.swing.JLabel jLabel2;
  private javax.swing.JLabel jLabel3;
  private javax.swing.JLabel jLabel4;
  private javax.swing.JLabel jLabel5;
  private javax.swing.JLabel jLabel6;
  private javax.swing.JLabel jLabel7;
  private javax.swing.JLabel jLabel8;
  private javax.swing.JLabel jLabel9;
  private javax.swing.JMenu jMenu1;
  private javax.swing.JMenuItem jMenuItem1;
  private javax.swing.JMenuItem jMenuItem2;
  private javax.swing.JMenuItem jMenuItem3;
  private javax.swing.JPanel jPanel3;
  private javax.swing.JScrollPane jScrollPane1;
  private javax.swing.JScrollPane jScrollPane2;
  private javax.swing.JScrollPane jScrollPane3;
  private javax.swing.JScrollPane jScrollPane4;
  private javax.swing.JScrollPane jScrollPane5;
  private javax.swing.JPopupMenu.Separator jSeparator1;
  private javax.swing.JTextArea jTextArea1;
  private javax.swing.JButton jbtnAddRow;
  private javax.swing.JButton jbtnExportSpendAnalysis;
  private javax.swing.JButton jbtnUpWaterCount;
  protected javax.swing.JComboBox jcboMonths;
  protected javax.swing.JComboBox jcboSessionType;
  protected javax.swing.JComboBox jcboWeeks;
  protected javax.swing.JTabbedPane jcompDetails;
  private javax.swing.ButtonGroup jgroupHistoryFilter;
  private javax.swing.JLabel jlblCurrentTime;
  private javax.swing.JLabel jlblSearch;
  private javax.swing.JLabel jlblStatus;
  private javax.swing.JMenuBar jmenuBar;
  private javax.swing.JMenu jmenuHelp;
  private javax.swing.JMenuItem jmenuItemAbout;
  private javax.swing.JMenuItem jmenuItemSave;
  private javax.swing.JPanel jpanHistory;
  private javax.swing.JPanel jpanSpend;
  protected javax.swing.JPanel jpanSpendAnalysis;
  protected javax.swing.JPanel jpanSpendSearchInput;
  private javax.swing.JPanel jpanWater;
  private javax.swing.JPanel jpanWork;
  protected javax.swing.JRadioButton jradMonthFilter;
  protected javax.swing.JRadioButton jradRangeFilter;
  protected javax.swing.JRadioButton jradWeekFilter;
  protected javax.swing.JTable jtblHistory;
  protected javax.swing.JTable jtblSpend;
  protected javax.swing.JTable jtblSpendAnalysis;
  protected javax.swing.JTextField jtxtBeginDateFilter;
  protected javax.swing.JTextField jtxtBreakBeginTime;
  protected javax.swing.JTextField jtxtBreakEndTime;
  protected javax.swing.JTextField jtxtEndDateFilter;
  protected javax.swing.JTextField jtxtExpectOutTime;
  protected javax.swing.JTextField jtxtInTime;
  protected javax.swing.JTextField jtxtMonthWorkedHours;
  protected javax.swing.JTextField jtxtMustWorkHoursToday;
  protected javax.swing.JTextArea jtxtNote;
  protected javax.swing.JTextField jtxtOutTime;
  protected org.tnmk.worktime.gui.widget.text.JCustomTextField jtxtSpendSearch;
  protected javax.swing.JTextField jtxtSumMonthSpend;
  protected javax.swing.JTextField jtxtSumSpend;
  protected javax.swing.JTextField jtxtSumWeekSpend;
  protected javax.swing.JTextField jtxtWater;
  protected javax.swing.JTextField jtxtWaterAlertPeriod;
  protected javax.swing.JTextField jtxtWeekWorkedHoursHistory;
  protected javax.swing.JTextField jtxtWorkedHours;
  // End of variables declaration//GEN-END:variables

  public SessionService getService() {
    return service;
  }

  public void setService(SessionService service) {
    this.service = service;
  }

  public DetailController getDetailController() {
    return detailController;
  }

  public HistoryController getHistoryController() {
    return historyController;
  }

  public WaterRemindController getWaterRemindController() {
    return waterRemindController;
  }

  public javax.swing.JTable getJtblHistory() {
    return jtblHistory;
  }

  public javax.swing.JTable getJtblSpend() {
    return jtblSpend;
  }

  public javax.swing.JTable getJtblSpendAnalysis() {
    return jtblSpendAnalysis;
  }
}
